import java.awt.*;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferStrategy;
import java.util.ArrayList;

import javax.swing.JFrame;
import javax.swing.JPanel;




public class GameMain extends Canvas {

	/**
	 * 
	 */
	private static final long serialVersionUID = 45;
	private BufferStrategy strategy;
	private boolean gameRunning = true;
	public ArrayList<SpaceObject> spaceObject = new ArrayList<SpaceObject>();
	private ArrayList<SpaceObject> removeList = new ArrayList<SpaceObject>();
	
	private SpaceObject ship;
	private double shipSpeed = 300;
	private long lastFire = 0;
	private long fireInterval = 150;
	public int enemyCount;
	public int level=1;
	public Level l;
	String message="";
	private boolean leftPressed=false;
	private boolean rightPressed=false;
	private boolean firePressed=false;
	private boolean waitingForKeyPress=false;
	private boolean logicRequiredThisLoop=false;
	public GameMain(){
		
		JFrame container = new JFrame("Super Space Shooter 19");
	
		JPanel panel =(JPanel) container.getContentPane();
		panel.setPreferredSize(new Dimension(800,600));
		panel.setLayout(null);
		
		
		setIgnoreRepaint(true);
		panel.add(this);
		
		setBounds(0,0,800,600);
		
		container.setUndecorated(false);
		container.pack();
		container.setResizable(false);
		container.setVisible(true);
		
		container.addWindowListener(new WindowAdapter(){
			public void windowClosing(WindowEvent e){
				System.exit(0);
			}
		});
		
		addKeyListener(new KeyInputHandler());
		
		requestFocus();
		
		createBufferStrategy(2);
		strategy =getBufferStrategy();
		l=new Level(this);
		initSpaceObject();
		
	}
	
	private void startGame(){
		
		spaceObject.clear();
		initSpaceObject();
		
		leftPressed =false;
		rightPressed=false;
		firePressed=false;
	}
	
	private void initSpaceObject() {
		ship = new Ship(this,"Sprite/ship.gif", 370, 550);
		
		spaceObject.add(ship);
		
		enemyCount = 0;
		l.getLevel();
		
	}

	public void updateLogic()
	{
		logicRequiredThisLoop = true;
	}
	public void notifyDeath()
	{
		message="you lost";
		waitingForKeyPress=true;
	}
	
	public void tryToFire(){
		if(System.currentTimeMillis()-lastFire<fireInterval){
			return;
			
		}
		
		lastFire = System.currentTimeMillis();
		Shot shot = new Shot(this,"Sprite/shot.gif", ship.getX()+10,ship.getY()-30);
		spaceObject.add(shot);
	}
	
	public void removeSpaceObject(SpaceObject spaceObj){
		removeList.add(spaceObj);
	}
	public void notifyWin(){
		message="Level Completed!";
		level++;
		waitingForKeyPress = true;
	}
	public void notifyEnemyKilled(){
		enemyCount--;
		
		if(enemyCount ==0)
		{
			notifyWin();
			
		}
		
		for(int i=0;i<spaceObject.size();i++)
		{
			SpaceObject spaceObj =(SpaceObject) spaceObject.get(i);
		
			if(spaceObj instanceof EnemyObject){
				spaceObj.setHorMove(spaceObj.getHorMove()*1.02);
			}
		}
		
	}
	private void startLoop() {
		long loopTime= System.currentTimeMillis();
		
		while(gameRunning){
			
			long del = System.currentTimeMillis()-loopTime;
			loopTime = System.currentTimeMillis();
			
			Graphics2D g = (Graphics2D)strategy.getDrawGraphics();
			g.setColor(Color.BLACK);
			g.fillRect(0, 0, 800, 600);
			
			if(!waitingForKeyPress){
				for(int i = 0; i<spaceObject.size();i++)
				{
					SpaceObject	 spaceobj = (SpaceObject) spaceObject.get(i);
					spaceobj.move(del);
				}
			}
			
			for(int i=0; i<spaceObject.size();i++)
			{
				SpaceObject spaceObj=(SpaceObject) spaceObject.get(i);
				
				spaceObj.draw(g);
			}
			
			for(int p=0;p<spaceObject.size();p++)
			{
				for(int s=p+1;s<spaceObject.size();s++)
				{
					SpaceObject one=(SpaceObject)spaceObject.get(p);
					SpaceObject two=(SpaceObject)spaceObject.get(s);
					
					if(one.collidesWith(two)){
						one.collidedWith(two);
						two.collidedWith(one);
					}
				}
			}
			spaceObject.removeAll(removeList);
			removeList.clear();
		
			if(logicRequiredThisLoop){
				for(int i=0; i<spaceObject.size();i++)
				{
					SpaceObject spaceObj = (SpaceObject)spaceObject.get(i);
					spaceObj.doLogic();
					
				}
				logicRequiredThisLoop=false;
			}
			if (waitingForKeyPress) {
				g.setColor(Color.white);
				g.drawString(message,(800-g.getFontMetrics().stringWidth(message))/2,250);
				g.drawString("Press any key",(800-g.getFontMetrics().stringWidth("Press any key"))/2,300);
			}
			g.dispose();
			strategy.show();
			
			ship.setHorMove(0);
			
			if((leftPressed) &&(!rightPressed))
			{
				ship.setHorMove(-shipSpeed);			
			}
			else if((rightPressed)&&(!leftPressed))
			{
				ship.setHorMove(shipSpeed);
			}
			if(firePressed){
				tryToFire();
			}
			
			try{Thread.sleep(10);}catch(Exception e){}
		}
	}
	private class KeyInputHandler extends KeyAdapter{
		
		private int pressCount=1;
		
		public void keyPressed(KeyEvent e)
		{
			
			if(waitingForKeyPress){
				return;
			}
			
			if(e.getKeyCode()==KeyEvent.VK_LEFT){
				leftPressed=true;
				
			}
			if(e.getKeyCode()==KeyEvent.VK_RIGHT){
				rightPressed=true;
				
			}
			if(e.getKeyCode()==KeyEvent.VK_SPACE){
				firePressed=true;
				
			}
			
		}
	
		public void keyReleased(KeyEvent e){
		
			if (waitingForKeyPress) {
				return;
			}
			
			if (e.getKeyCode() == KeyEvent.VK_LEFT) {
				leftPressed = false;
			}
			if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
				rightPressed = false;
			}
			if (e.getKeyCode() == KeyEvent.VK_SPACE) {
				firePressed = false;
			}
		}
		public void keyTyped(KeyEvent e){
			if(waitingForKeyPress){
				if(pressCount==1){
					waitingForKeyPress=false;
					startGame();
					pressCount=0;
				}else{
					pressCount++;
				}
			}
		}
	}
	public static void main(String argv[]) {
		GameMain g =new GameMain();

   
		g.startLoop();
	}

	
}
